package org.spring.blog.service.impl;

import org.spring.blog.dao.CategoryDao;
import org.spring.blog.pojo.Category;
import org.spring.blog.response.ResponseResult;
import org.spring.blog.response.ResponseState;
import org.spring.blog.service.ICategoryService;
import org.spring.blog.utils.LRConstants;
import org.spring.blog.utils.SnowflakeIdWorker;
import org.spring.blog.utils.TextUtil;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class CategoryService implements ICategoryService {

    private final SnowflakeIdWorker snowflakeIdWorker;

    private final CategoryDao categoryDao;

    public CategoryService(SnowflakeIdWorker snowflakeIdWorker, CategoryDao categoryDao) {
        this.snowflakeIdWorker = snowflakeIdWorker;
        this.categoryDao = categoryDao;
    }

    /**
     * 删除分类
     *
     * @param _categoryId 分类对象id
     * @return 自定义返回对象
     */
    @Override
    public ResponseResult deleteCategory(String _categoryId) {
        int i = categoryDao.updateCategoryStatus(_categoryId, LRConstants.db_ban_status);

        if (i == 0) {
            return ResponseResult.failed(ResponseState.data_not_have_message, ResponseState.data_not_have_code);
        }
        return ResponseResult.success();
    }

    /**
     * 添加分类
     * 要求
     * 1.管理员权限
     *
     * @param _category 分类对象
     * @return 自定义返回对象
     */
    @Override
    public ResponseResult insertCategory(Category _category) {
        // check env
        // check data
        if (TextUtil.isEmpty(_category.getName())) {
            return ResponseResult.failed(ResponseState.category_name_cant_empty_message, ResponseState.category_name_cant_empty_code);
        }

        if (TextUtil.isEmpty(_category.getPinyin())) {
            return ResponseResult.failed(ResponseState.category_pinyin_cant_empty_message, ResponseState.category_pinyin_cant_empty_code);
        }

        if (TextUtil.isEmpty(_category.getDescription())) {
            return ResponseResult.failed(ResponseState.category_description_cant_empty_message, ResponseState.category_description_cant_empty_code);
        }
        if (_category.getOrder() <= 0L) {
            _category.setOrder(LRConstants.db_default_order_value);
        }

        // complete data
        _category.setId(String.valueOf(snowflakeIdWorker.nextId()))
                .setStatus(LRConstants.db_publish_status)
                .setCreateTime(new Date())
                .setUpdateTime(new Date());

        // change data
        categoryDao.save(_category);
        return ResponseResult.success();
    }

    /**
     * 获取分类
     * <p>
     * 需要管理员权限
     *
     * @param _categoryId 分类id
     * @return 自定义返回对象
     */
    @Override
    public ResponseResult queryCategory(String _categoryId) {

        // check data
        Category oneById = categoryDao.findOneById(_categoryId);

        if (oneById == null) {
            return ResponseResult.failed(ResponseState.data_not_have_message, ResponseState.data_not_have_code);
        }

        // return data
        return ResponseResult.success().setData(oneById);
    }

    /**
     * 获取分类列表
     *
     * @return 自定义返回对象
     */
    @Override
    public ResponseResult listCategories() {

        // complete date
        Sort sort = new Sort(Sort.Direction.DESC, "createTime", "order");

        List<Category> categories = categoryDao.findAll(new Specification<Category>() {

            private static final long serialVersionUID = -6209670600006640651L;

            @Override
            public Predicate toPredicate(Root<Category> _root, CriteriaQuery<?> _criteriaQuery, CriteriaBuilder _criteriaBuilder) {
                return _criteriaBuilder.equal(_root.get("status").as(String.class), LRConstants.db_publish_status);
            }
        }, sort);


        // return data
        return ResponseResult.success().setData(categories);
    }

    /**
     * 管理员获取分类列表
     *
     * @return 自定义返回对象
     */
    @Override
    public ResponseResult listCategoriesForAdmin() {

        // complete date
        Sort sort = new Sort(Sort.Direction.DESC, "createTime", "order");

        List<Category> categories = categoryDao.findAll(sort);


        // return data
        return ResponseResult.success().setData(categories);
    }

    /**
     * 更新分类
     *
     * @param _categoryId 分类id
     * @param _category   分类对象
     * @return 自定义返回对象
     */
    @Override
    public ResponseResult updateCategory(String _categoryId, Category _category) {
        // check data
        Category oneById = categoryDao.findOneById(_categoryId);

        if (oneById == null) {
            return ResponseResult.failed(ResponseState.data_not_have_message, ResponseState.data_not_have_code);
        }
        // complete data
        if (!TextUtil.isEmpty(_category.getName())) {
            oneById.setName(_category.getName());
        }

        if (!TextUtil.isEmpty(_category.getDescription())) {
            oneById.setDescription(_category.getDescription());
        }

        if (!TextUtil.isEmpty(_category.getPinyin())) {
            oneById.setPinyin(_category.getPinyin());
        }

        if (TextUtil.notEmpty(_category.getStatus())) {
            oneById.setStatus(_category.getStatus());
        }

        oneById.setUpdateTime(new Date())
                .setOrder(_category.getOrder());

        // change data
        categoryDao.save(oneById);
        return ResponseResult.success();
    }
}
